package org.easier.framework.fastjson.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.ToStringSerializer;
import org.easier.framework.json.JsonAdapter;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

public class Fastjson implements JsonAdapter {
    private static final SerializeConfig serializeConfig = new SerializeConfig();

    static {
        serializeConfig.put(Long.class, ToStringSerializer.instance);
        serializeConfig.put(Long.TYPE, ToStringSerializer.instance);
        serializeConfig.put(LocalDateTime.class, DateToStringSerializer.instance);
    }

    private final boolean isProd;

    public Fastjson(boolean isProd) {
        this.isProd = isProd;
    }

    @Override
    public String serialize(Object entity) {
        if (!isProd) {
            return JSON.toJSONString(entity, serializeConfig, SerializerFeature.WriteMapNullValue, SerializerFeature.PrettyFormat);
        }
        return JSON.toJSONString(entity, serializeConfig, SerializerFeature.WriteMapNullValue);
    }

    @Override
    public String serialize(Object entity, boolean notNull) {
        if (!isProd) {
            if (notNull) {
                return JSON.toJSONString(entity, serializeConfig, SerializerFeature.PrettyFormat);
            }
            return JSON.toJSONString(entity, serializeConfig, SerializerFeature.WriteMapNullValue, SerializerFeature.PrettyFormat);
        }
        if (notNull) {
            return JSON.toJSONString(entity, serializeConfig, SerializerFeature.PrettyFormat);
        }
        return JSON.toJSONString(entity, serializeConfig, SerializerFeature.WriteMapNullValue);
    }

    @Override
    public <T> T deserialize(String jsonContent, Class<T> clazz) {
        return JSON.parseObject(jsonContent, clazz);
    }


    @Override
    public <T> T toObject(String content, Class<T> clazz) {
        return JSONObject.parseObject(content, clazz);
    }

    @Override
    public <T> T toObject(String content, String key, Class<T> clazz) {
        return JSONObject.parseObject(content).getObject(key, clazz);
    }

    @Override
    public <T> List<T> deserializeList(String content, Class<T> clazz) {
        return JSON.parseObject(content, new TypeReference<List<T>>(clazz) {
        });
    }

    @Override
    public <K, V> Map<K, V> deserializeMap(String content, Class<K> keyClazz, Class<V> valueClazz) {
        return JSON.parseObject(content, new TypeReference<Map<K, V>>(keyClazz, valueClazz) {
        });
    }
}
